<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test.js"></script>
<script src="../resources/common.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>

<script>
description("Tests structured de-cloning of empty HMAC keys");

jsTestIsAsync = true;

// It used to be possible to import empty HMAC keys, so it is possible that
// such keys were persisted to storage. This test verifies that such keys can
// still be successfully de-serialized and used.
//
// The version number of the serialized format used is 7.

function deserializeTestKeys()
{
    function createKeyFromSerialized(serializedBytesHex)
    {
        return internals.deserializeBuffer(hexStringToUint8Array(serializedBytesHex).buffer);
    }

    debug("\nDeserializing empty HMAC SHA-1 key...");
    var sha1Key = createKeyFromSerialized("ff073f004b0200051900");

    key = sha1Key;
    shouldEvaluateAs("key.type", "secret");
    shouldEvaluateAs("key.extractable", true);
    shouldEvaluateAs("key.algorithm.name", "HMAC");
    shouldEvaluateAs("key.algorithm.length", 0);
    shouldEvaluateAs("key.algorithm.hash.name", "SHA-1");
    shouldBe("key.usages", '["sign", "verify"]');

    debug("\nDeserializing empty HMAC SHA-256 key...");
    var sha256Key = createKeyFromSerialized("ff073f004b0200061900");

    key = sha256Key;
    shouldEvaluateAs("key.type", "secret");
    shouldEvaluateAs("key.extractable", true);
    shouldEvaluateAs("key.algorithm.name", "HMAC");
    shouldEvaluateAs("key.algorithm.length", 0);
    shouldEvaluateAs("key.algorithm.hash.name", "SHA-256");
    shouldBe("key.usages", '["sign", "verify"]');

    return {
        sha1: sha1Key,
        sha256: sha256Key
    };
}


Promise.resolve(deserializeTestKeys()).then(function(result) {
    keys = result;

    debug("\ncalling verify() with a valid signature (SHA-1) ...");
    return crypto.subtle.verify("HMAC", keys.sha1, hexStringToUint8Array("fbdb1d1b18aa6c08324b7d64b71fb76370690e1d"), hexStringToUint8Array(""));
}).then(function(result) {
    verifyResult = result;
    shouldEvaluateAs("verifyResult", true);

    debug("\ncalling verify() with an invalid signature (SHA-1) ...");
    return crypto.subtle.verify("HMAC", keys.sha1, hexStringToUint8Array("fbdb1d1b18aa6c08324b7d64b71fb76370690e1e"), hexStringToUint8Array(""));
}).then(function(result) {
    verifyResult = result;
    shouldEvaluateAs("verifyResult", false);

    debug("\ncalling sign() (SHA-1) over empty input...");
    return crypto.subtle.sign("HMAC", keys.sha1, hexStringToUint8Array(""));
}).then(function(result) {
    bytesShouldMatchHexString("signature", "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d", result);

    debug("\ncalling verify() with a valid signature (SHA-256) ...");
    return crypto.subtle.verify("HMAC", keys.sha256, hexStringToUint8Array("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"), hexStringToUint8Array(""));
}).then(function(result) {
    verifyResult = result;
    shouldEvaluateAs("verifyResult", true);

    debug("\ncalling verify() with an invalid signature (SHA-256) ...");
    return crypto.subtle.verify("HMAC", keys.sha256, hexStringToUint8Array("0000"), hexStringToUint8Array(""));
}).then(function(result) {
    verifyResult = result;
    shouldEvaluateAs("verifyResult", false);

    debug("\ncalling sign() (SHA-256) over empty input...");
    return crypto.subtle.sign("HMAC", keys.sha256, hexStringToUint8Array(""));
}).then(function(result) {
    bytesShouldMatchHexString("signature", "b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad", result);
}).then(finishJSTest, failAndFinishJSTest);

</script>

</body>
</html>
